package com.campus.help.service;

import com.campus.help.dto.TaskPublishRequest;
import com.campus.help.entity.Task;
import com.campus.help.enums.TaskStatus;
import com.campus.help.repository.TaskRepository;
import com.campus.help.util.TaskUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@RequiredArgsConstructor
public class TaskService {
    
    private final TaskRepository taskRepository;
    private final UserService userService;
    
    /**
     * 发布任务
     * @param request 任务发布请求
     * @param publisherId 发布者学号
     * @return 发布结果
     */
    public String publishTask(TaskPublishRequest request, String publisherId) {
        // 验证发布者是否存在
        if (!userService.existsByStudentId(publisherId)) {
            throw new RuntimeException("发布者不存在");
        }
        
        // 验证截止时间
        if (!TaskUtil.isValidDeadline(request.getDeadline())) {
            throw new RuntimeException("截止时间必须晚于当前时间");
        }
        
        // 创建任务
        Task task = new Task(
            TaskUtil.generateTaskId(),
            request.getTitle(),
            request.getDescription(),
            request.getDeadline(),
            request.getReward(),
            TaskStatus.PENDING.name(),
            publisherId,
            null,
            LocalDateTime.now(),
            LocalDateTime.now()
        );
        
        taskRepository.save(task);
        return "任务发布成功";
    }
    
    /**
     * 接受任务
     * @param taskId 任务ID
     * @param acceptorId 接受者学号
     * @return 接受结果
     */
    public String acceptTask(String taskId, String acceptorId) {
        // 验证接受者是否存在
        if (!userService.existsByStudentId(acceptorId)) {
            throw new RuntimeException("接受者不存在");
        }
        
        // 限制：每人最多同时接受3个进行中任务
        long acceptedCount = taskRepository.findByAcceptorId(acceptorId).stream()
            .filter(t -> TaskStatus.ACCEPTED.name().equals(t.getStatus()))
            .count();
        if (acceptedCount >= 3) {
            throw new RuntimeException("每人最多同时接受3个任务");
        }
        
        // 查找任务
        Optional<Task> taskOpt = taskRepository.findByTaskId(taskId);
        if (!taskOpt.isPresent()) {
            throw new RuntimeException("任务不存在");
        }
        
        Task task = taskOpt.get();
        
        // 验证任务是否可以接受
        if (!TaskUtil.canAcceptTask(task)) {
            throw new RuntimeException("任务不可接受（任务状态不是PENDING或已过期）");
        }
        
        // 检查用户是否有冲突的任务
        if (TaskUtil.hasConflictTask(taskRepository.findAll(), acceptorId)) {
            throw new RuntimeException("您已有未完成的任务，不能接受新任务");
        }
        
        // 不能接受自己发布的任务
        if (acceptorId.equals(task.getPublisherId())) {
            throw new RuntimeException("不能接受自己发布的任务");
        }
        
        // 更新任务状态
        task.setStatus(TaskStatus.ACCEPTED.name());
        task.setAcceptorId(acceptorId);
        task.setUpdateTime(LocalDateTime.now());
        
        taskRepository.save(task);
        return "任务接受成功";
    }
    
    /**
     * 完成任务
     * @param taskId 任务ID
     * @param userId 用户学号
     * @return 完成结果
     */
    public String completeTask(String taskId, String userId) {
        Optional<Task> taskOpt = taskRepository.findByTaskId(taskId);
        if (!taskOpt.isPresent()) {
            throw new RuntimeException("任务不存在");
        }
        
        Task task = taskOpt.get();
        
        // 只有任务接受者或发布者可以标记任务完成
        if (!userId.equals(task.getAcceptorId()) && !userId.equals(task.getPublisherId())) {
            throw new RuntimeException("只有任务接受者或发布者可以标记任务完成");
        }
        
        if (!TaskStatus.ACCEPTED.name().equals(task.getStatus())) {
            throw new RuntimeException("任务状态不正确");
        }
        
        task.setStatus(TaskStatus.COMPLETED.name());
        task.setUpdateTime(LocalDateTime.now());
        
        taskRepository.save(task);
        return "任务完成";
    }
    
    /**
     * 获取所有任务列表
     * @return 任务列表
     */
    public List<Task> getAllTasks() {
        return taskRepository.findAll();
    }
    
    /**
     * 根据状态获取任务列表
     * @param status 任务状态
     * @return 任务列表
     */
    public List<Task> getTasksByStatus(TaskStatus status) {
        return taskRepository.findByStatus(status.name());
    }
    
    /**
     * 获取用户发布的任务
     * @param publisherId 发布者学号
     * @return 任务列表
     */
    public List<Task> getTasksByPublisher(String publisherId) {
        return taskRepository.findByPublisherId(publisherId);
    }
    
    /**
     * 获取用户接受的任务
     * @param acceptorId 接受者学号
     * @return 任务列表
     */
    public List<Task> getTasksByAcceptor(String acceptorId) {
        return taskRepository.findByAcceptorId(acceptorId);
    }
    
    /**
     * 根据ID获取任务详情
     * @param taskId 任务ID
     * @return 任务详情
     */
    public Optional<Task> getTaskById(String taskId) {
        return taskRepository.findByTaskId(taskId);
    }
    
    /**
     * 放弃任务
     * @param taskId 任务ID
     * @param acceptorId 接受者学号
     * @return 放弃结果
     */
    public String abandonTask(String taskId, String acceptorId) {
        Optional<Task> taskOpt = taskRepository.findByTaskId(taskId);
        if (!taskOpt.isPresent()) {
            throw new RuntimeException("任务不存在");
        }
        Task task = taskOpt.get();
        if (!TaskStatus.ACCEPTED.name().equals(task.getStatus())) {
            throw new RuntimeException("任务当前不可放弃");
        }
        if (!acceptorId.equals(task.getAcceptorId())) {
            throw new RuntimeException("只有接受者本人可以放弃该任务");
        }
        task.setStatus(TaskStatus.PENDING.name());
        task.setAcceptorId(null);
        task.setUpdateTime(LocalDateTime.now());
        taskRepository.save(task);
        return "任务已放弃";
    }
    
    /**
     * 撤回任务（仅发布者，任务为PENDING或ACCEPTED时允许）
     * @param taskId 任务ID
     * @param publisherId 发布者学号
     * @return 撤回结果
     */
    public String withdrawTask(String taskId, String publisherId) {
        Optional<Task> taskOpt = taskRepository.findByTaskId(taskId);
        if (!taskOpt.isPresent()) {
            throw new RuntimeException("任务不存在");
        }
        Task task = taskOpt.get();
        if (!publisherId.equals(task.getPublisherId())) {
            throw new RuntimeException("只有发布者本人可以撤回该任务");
        }
        if (!TaskStatus.PENDING.name().equals(task.getStatus()) && !TaskStatus.ACCEPTED.name().equals(task.getStatus())) {
            throw new RuntimeException("只有待接受或进行中的任务可以撤回");
        }
        // 直接物理删除任务
        taskRepository.delete(task);
        return "任务已撤回";
    }
    
    /**
     * 修改任务（仅发布者，任务为PENDING或ACCEPTED时允许）
     */
    public String updateTask(String taskId, String publisherId, TaskPublishRequest request) {
        Optional<Task> taskOpt = taskRepository.findByTaskId(taskId);
        if (!taskOpt.isPresent()) {
            throw new RuntimeException("任务不存在");
        }
        Task task = taskOpt.get();
        if (!publisherId.equals(task.getPublisherId())) {
            throw new RuntimeException("只有发布者本人可以修改该任务");
        }
        if (!TaskStatus.PENDING.name().equals(task.getStatus()) && !TaskStatus.ACCEPTED.name().equals(task.getStatus())) {
            throw new RuntimeException("只有待接受或进行中的任务可以修改");
        }
        // 校验截止时间
        if (!TaskUtil.isValidDeadline(request.getDeadline())) {
            throw new RuntimeException("截止时间必须晚于当前时间");
        }
        task.setTitle(request.getTitle());
        task.setDescription(request.getDescription());
        task.setReward(request.getReward());
        task.setDeadline(request.getDeadline());
        task.setUpdateTime(java.time.LocalDateTime.now());
        taskRepository.save(task);
        return "任务修改成功";
    }
}